JS30 Day 25 筆記


Posted by GL on 2023-05-23

目標

EventTarget.addEventListener中事件的 capturebubbleonce 方法,以及事件代理(propagation)

Demo

step 1 : 了解 HTML 的架構與建立 click 監聽事件

<div class="one">
  <div class="two">
    <div class="three">
    </div>
  </div>
</div>
// 取得頁面的所有 div 元素
const divs = document.querySelectorAll('div');

function logText(e){
// console 印出當前 click 的 class name
  console.log(this.classList.value);
}

// 監聽所有 div 元素的 click 事件 
divs.forEach(div => div.addEventListener('click',logText));

step 2 : 點擊最裡面的 class name 為 three 的區塊,並查看 console.log 的結果

發現印出從最内層到最外層(three -> two -> one)

three
two
one

step 3 : 分析 addEventListener 的參數

// 第一個參數: 監聽的事件類型(event type)
// 第二個參數: 事件被觸發時,要執行的 callback function
// 第三個參數: options 是一個物件,可控制的屬性有 capture、once...等
addEventListener(type, listener, options)
divs.forEach(div => div.addEventListener('click', logText, {
  // 預設為false,表示事件的觸發順序為冒泡階段(由下往上的層級)
  // 若爲 true,則表示設定為捕獲階段(由上往下的層級。印出:one,two,three)
  capture: false, 
  //預設為 false,若設爲 true,則表示事件只監聽一次
  //執行後 removeEventListener
  once: false 
  //預設為 false,若設爲 true,則表示將無法在函式中使用 event.preventDefault() 方法。
  passive: false
}));

step 4 : stopPropagation()

e.stopPropagation:表示此處監聽到事件後,停止事件以捕獲或者冒泡的方式往下個層級傳遞,

function logText(e) {
  console.log(this.classList.value);
  e.stopPropagation(); // stop bubbling or capture 
}

補充: Event delegation

如果有很多類似的監聽事件,與其在每個元素中挂上監聽,較好的做法是統一監聽在這些元素的父元素


參考資料:


#JS 30







Related Posts

CSS保健室|border-image-slice

CSS保健室|border-image-slice

How to build CICD with Jenkins as code based on container

How to build CICD with Jenkins as code based on container

使用 Vue Cli 來建置Vue專案

使用 Vue Cli 來建置Vue專案


Comments